# 14-1 按P开始新游戏：鉴于游戏《外星人入侵》使用键盘来控制飞船，最好让玩家也能够通过按键来开始游戏。请添加让玩家在按P时开始游戏的代码。
# 也许这样做会有所帮助：将check_play_button()的一些代码提取出来，放到一个名为start_game()的函数中，并在check_play_button()和check_keydown_events()中调用这个函数。
print("14-1: 按p开始游戏")
# done

print("14-2: 射击矩形")
# 14-2 射击练习：创建一个矩形，它在屏幕右边缘以固定的速度上下移动。然后，在屏幕左边缘创建一艘飞船，玩家可上下移动该飞船，并射击前述矩形目标。
# 添加一个用于开始游戏的Play按钮，在玩家三次未击中目标时结束游戏，并重新显示Play按钮，让玩家能够通过单击该按钮来重新开始游戏。
import pygame
import sys
import os
from random import randint, random
from pygame.sprite import Group
from game_stats import GameStats
from button import Button
from settings import Settings

def test_bullet_short_rect():
    pygame.init()
    screen = pygame.display.set_mode((1200, 800))
    screen_rect = screen.get_rect()
    pygame.display.set_caption('14-2 射击矩形')

    # 加载图像
    ship_path = os.path.join(os.path.dirname(__file__), 'images', 'ship2.bmp')
    print('ship_path路径:', ship_path)
    ship_image = pygame.image.load(ship_path)
    ship_rect = ship_image.get_rect()

    # 图像放屏幕左中
    ship_rect.centery = screen_rect.centery
    ship_rect.left = screen_rect.left
    speed = 1

    # 创建一个用于存储子弹的编组
    bullets = Group()
    aim_rect = AimRect(screen)
    ai_settings = Settings()
    stats = GameStats(ai_settings)
    button = Button(ai_settings, screen, "开始")
    # 游戏主循环
    while True:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                sys.exit()
            elif event.type == pygame.KEYDOWN:
                if event.key == pygame.K_SPACE:
                    # 发射子弹
                    new_bullet = Bullet(screen, ship_rect.centery, ship_rect.left)
                    bullets.add(new_bullet)
                elif event.key == pygame.K_ESCAPE:
                    pygame.quit()
                    sys.exit()
            elif event.type == pygame.MOUSEBUTTONDOWN:
                if button.rect.collidepoint(pygame.mouse.get_pos()):
                    stats.game_active = True
                    stats.ship_left = 3
                    bullets.empty()
                    """重置飞船位置到左侧中间"""
                    ship_rect.centery = screen_rect.centery
                    ship_rect.left = 20  # 距离左边缘有一点距离
                    aim_rect = AimRect(screen)  # 重置目标位置


        if stats.game_active:
            # 每一帧检测键盘状态
            keys = pygame.key.get_pressed()
            if keys[pygame.K_RIGHT] and ship_rect.right < screen_rect.right:
                ship_rect.x += speed
            if keys[pygame.K_LEFT] and ship_rect.left > 0:
                ship_rect.x -= speed
            if keys[pygame.K_UP] and ship_rect.top > 0:
                ship_rect.y -= speed
            if keys[pygame.K_DOWN] and ship_rect.bottom < screen_rect.bottom:
                ship_rect.y += speed

            bullets.update()
            # 移除已消失的子弹
            for b in bullets.copy():
                if b.rect.left > screen_rect.right:
                    bullets.remove(b)
                    stats.ship_left -= 1
                    # 检查游戏是否结束
                    if stats.ship_left <= 0:
                        stats.game_active = False
                        # 检测子弹与目标的碰撞
            collisions = pygame.sprite.spritecollide(aim_rect, bullets, True)
            if collisions:
                # 击中目标后，创建新的目标
                aim_rect = AimRect(screen)
                aim_rect.speed_factor *= 2

            # 更新目标位置
            aim_rect.update()
            screen.fill((230, 230, 230))
            for bullet in bullets.sprites():
                bullet.draw_bullet()
            aim_rect.update()

        # 如果游戏牌非活跃状态，就绘制play按钮
        if not stats.game_active:
            button.draw_button()
        aim_rect.draw_aimrect()
        screen.blit(ship_image, ship_rect)
        pygame.display.flip()


class Bullet(pygame.sprite.Sprite):
    def __init__(self, screen, ship_centery, ship_left):
        super().__init__()
        self.screen = screen
        self.rect = pygame.Rect(0, 0, 6, 2)
        self.rect.centery = ship_centery
        self.rect.left = ship_left

        # 存储小数表示子弹位置
        self.x = float(self.rect.x)
        self.color = 50, 50, 50

    def update(self):
        self.x += 2
        self.rect.x = self.x

    def draw_bullet(self):
        pygame.draw.rect(self.screen, self.color, self.rect)



class AimRect(pygame.sprite.Sprite):
    def __init__(self, screen):
        super().__init__()
        self.screen = screen
        self.screen_rect = screen.get_rect()
        self.rect = pygame.Rect(0, 0, 20, 100)

        # 矩形位置
        self.rect.x = self.screen_rect.right - 20
        self.rect.y = randint(self.rect.top + 10, self.screen_rect.bottom - 10)

        # 角色移动速度
        self.y = float(self.rect.y)
        self.rect_color = 255, 0, 6
        self.speed_factor = 0.5
        # 1表示向下移动，-1表示向上移动
        self.direction = 1

    def draw_aimrect(self):
        """在屏幕上绘制子弹"""
        pygame.draw.rect(self.screen, self.rect_color, self.rect)

    def update(self):
        """上下移动角色"""
        # 更新飞船的y
        if self.rect.bottom >= self.screen_rect.bottom:
            self.direction = -1

        if self.rect.top <= 0:
            self.direction = 1

        # 根据方向更新位置
        self.y += self.speed_factor * self.direction
        self.rect.y = int(self.y)


test_bullet_short_rect()


# 14-3 有一定难度的射击练习：以你为完成练习14-2而做的工作为基础，让标靶的移动速度随游戏进行而加快，并在玩家单击Play按钮时将其重置为初始值。
# # done
# 14-4 历史最高分：每当玩家关闭并重新开始游戏《外星人入侵》时，最高分都将被重置。请修复这个问题，
# 调用sys.exit()前将最高分写入文件，并当在GameStats中初始化最高分时从文件中读取它。
# done

# 14-5 重构：找出执行了多项任务的函数和方法，对它们进行重构，以让代码高效而有序。例如，对于check_bullet_alien_collisions()，
# 将其中在外星人群被消灭干净时开始新等级的代码移到一个名为start_new_level()的函数中；
# 又比如，对于Scoreboard的方法__init__()，
# 将其中调用四个不同方法的代码移到一个名为prep_images()的方法中，以缩短方法__init__()。
# 如果你重构了check_play_button()，
# 方法prep_images()也可为check_play_button()或start_game()提供帮助。
# 注意　重构项目前，请阅读附录D，了解如果重构时引入了bug，如何将项目恢复到可正确运行的状态。
# done

# 14-6 扩展游戏《外星人入侵》：想想如何扩展游戏《外星人入侵》。例如，可让外星人也能够向飞船射击，或者添加盾牌，让飞船躲到它后面，
# 使得只有从两边射来的子弹才能摧毁飞船。另外，还可以使用像pygame.mixer这样的模块来添加音效，如爆炸声和射击声。
# done
# 1，新增背景音乐控制 ，点击开始按钮或p按时才加载背景音乐，且游戏结束时音效暂停
# 2，新增发射子弹音效
# 3，新增外星人飞船碰撞音效
# 4，新增音量键 控制